#include "render/Renderer.h"
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

bool Renderer::init(const char* vs, const char* fs){
    glEnable(GL_DEPTH_TEST);
    cube = Mesh::Cube();
    plane = Mesh::Plane();
    return shader.loadFromFiles(vs,fs);
}

void Renderer::draw(const Game& game, const Camera& cam, int width, int height){
    glViewport(0,0,width,height);
    glClearColor(0.1f,0.12f,0.18f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    shader.use();
    glm::mat4 view = cam.view();
    glm::mat4 proj = cam.proj((float)width/(float)height);
    shader.setMat4("uView", &view[0][0]);
    shader.setMat4("uProj", &proj[0][0]);
    shader.setVec3("uLightDir", -0.5f, -1.0f, -0.3f);
    shader.setFloat("uAmbient", 0.25f);

    glm::mat4 model(1.0f);
    model = glm::scale(model, glm::vec3(game.level().width()*tileSize, 1.0f, game.level().height()*tileSize));
    model = glm::translate(glm::mat4(1.0f), glm::vec3(0,0,0));
    shader.setMat4("uModel", &model[0][0]);
    shader.setVec3("uColor", 0.2f,0.25f,0.3f);
    plane.draw();

    for(int y=0;y<game.level().height();++y){
        for(int x=0;x<game.level().width();++x){
            if(game.level().tileAt(x,y)==Tile::Wall){
                glm::mat4 m(1.0f);
                m = glm::translate(m, glm::vec3(x*tileSize, 0.5f, y*tileSize));
                shader.setMat4("uModel", &m[0][0]);
                shader.setVec3("uColor", 0.35f,0.35f,0.4f);
                cube.draw();
            }
        }
    }
    for(const auto& gpos : game.level().goals()){
        glm::mat4 m(1.0f);
        m = glm::translate(m, glm::vec3(gpos.x*tileSize, 0.25f, gpos.y*tileSize));
        m = glm::scale(m, glm::vec3(0.5f));
        shader.setMat4("uModel", &m[0][0]);
        shader.setVec3("uColor", 0.9f,0.8f,0.2f);
        cube.draw();
    }
    for(const auto& bpos : game.state().boxes){
        glm::mat4 m(1.0f);
        m = glm::translate(m, glm::vec3(bpos.x*tileSize, 0.5f, bpos.y*tileSize));
        shader.setMat4("uModel", &m[0][0]);
        shader.setVec3("uColor", 0.6f,0.35f,0.2f);
        cube.draw();
    }
    {
        glm::mat4 m(1.0f);
        m = glm::translate(m, glm::vec3(game.state().player.x*tileSize, 0.5f, game.state().player.y*tileSize));
        shader.setMat4("uModel", &m[0][0]);
        shader.setVec3("uColor", 0.2f,0.7f,0.3f);
        cube.draw();
    }
}